#!/bin/bash
# Download official package files.

# override with -n
do_release=true
# override with -m
#mirror="http://mirror.archlinux.no"
#mirror_arm="http://ftp.halifax.rwth-aachen.de/archlinux-arm/"
mirror_arm="http://de.mirror.archlinuxarm.org"
# override with -s
signatures=true
# override with -o
out_dir=.

base=${BASH_SOURCE[0]%/*}

err() {
	echo >&2 "baofficial: $*"
}

die() {
	err "FATAL: $*"
	exit 1
}

usage() {
	cat <<EOF
usage: baofficial [options] <package name>...

options
  -n           Do not release with barelease. Instead, simply download the package
               and signature files.
  -o <out>     Specify an output directory for package and signatur files. This is only
               useful with -n.
  -s           Do not download signatures. Using this without -n is normally an error.
  -m <mirror>  Specify an official repo mirror (default: $mirror).
EOF
}

pkg_info() {
	local pkg=$1
	local item=$2

	pacman "--config=$conffile" -Si "$pkg" |
	  grep "^$item" | cut -d: -f2- | sed 's/^ //' |
	  head -n1
}

_sudo() {
	if [[ $EUID != 0 ]] ; then
		sudo "$@"
	else
		"$@"
	fi
}

parse_args() {
	while getopts no:sm:h flag ; do
		case "$flag" in
			n) do_release=false ;;
			o) out_dir=$OPTARG  ;;
			s) signatures=false ;;
			m) mirror=$OPTARG   ;;
			h) usage; exit      ;;
			*) usage; exit 1    ;;
		esac
	done

	shift $(( $OPTIND - 1 ))

	pkgnames=("$@")
}

check_args() {
	if (( "${#pkgnames[@]}" == 0 )) ; then
		die 'specify at least one package name'
	fi
}

cleanup() {
	_sudo rm -rf "$tmp"
}
trap cleanup EXIT

pacman_init() {
	local arch=$1

	local pacman_dir=$tmp/pacman/$arch
	local dbdir=$pacman_dir/db
	local logfile=$pacman_dir/pacman.log
	local conffile=$pacman_dir/pacman.conf

	mkdir -p "$dbdir"
	mkdir -p "${logfile%/*}"
	mkdir -p "${conffile%/*}"

#  if [[ $arch == "armv6h" || $arch == "armv7h" || $arch == "aarch64" ]];
#  then
    cat > "$conffile" <<EOF
[options]
Architecture = $arch
SigLevel    = Never
CacheDir    = $tmp/$arch
DBPath      = $dbdir
LogFile     = $logfile

[core]
Server = $mirror_arm/\$arch/\$repo

[extra]
Server = $mirror_arm/\$arch/\$repo

#[community]
#Server = $mirror_arm/\$arch/\$repo
EOF
#  else
#    cat > "$conffile" <<EOF
#[options]
#Architecture = $arch
#SigLevel    = Never
#CacheDir    = $tmp/$arch
#DBPath      = $dbdir
#LogFile     = $logfile

#[core]
#Server = $mirror/\$repo/os/$arch

#[extra]
#Server = $mirror/\$repo/os/$arch

#[community]
#Server = $mirror/\$repo/os/$arch
#EOF
#  fi

	err "syncing $arch package database..."

	# Sync db.
	_sudo pacman "--config=$conffile" -Sy > /dev/null
}

handle_package() {
	local pkgname=$1
	local arch=$2

	local pacman_dir=$tmp/pacman/$arch
	conffile=$pacman_dir/pacman.conf

	# Check existence.
	if ! pacman "--config=$conffile" -Si "$pkgname" &> /dev/null ; then
		echo "[WARN] $pkgname does not exist in the official repos"
    return
	fi

	# Get info.
	pkgver=$(pkg_info $pkgname Version)
	pkg_arch=$(pkg_info $pkgname Architecture)
	repo=$(pkg_info $pkgname Repository)

	# Download.
	(
	cd "$tmp"
	err "downloading files for $arch $pkgname..."
  curl -Os "$mirror_arm/$arch/$repo/$pkgname-$pkgver-$pkg_arch.pkg.tar.zst"
  curl -Os "$mirror_arm/$arch/$repo/$pkgname-$pkgver-$pkg_arch.pkg.tar.zst.sig"
	)
}

handle_finale() {
	if $do_release ; then
		"$base/barelease" -o "$tmp"/*.pkg.tar.zst
	else
		cp -i "$tmp"/*.pkg.tar.zst "$out_dir"
		if $signatures ; then
			cp -i "$tmp"/*.pkg.tar.zst.sig "$out_dir"
		fi
	fi
}

tmp=$(mktemp -d /tmp/baofficial.XXXXXXXX)

main() {
	parse_args "$@"
	check_args

  pacman_init aarch64

	for pkgname in "${pkgnames[@]}" ; do
    handle_package "$pkgname" aarch64
	done

	handle_finale
}

main "$@"
